<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>

</body>
<script>
	/**
	 * 解析路径字符串或数组，将其统一转换为路径段数组
	 * 处理带索引的路径段（如'arr[0]'），将其拆分为单独的路径段（['arr','0']）
	 * @param {string|Array} path - 要解析的路径，可以是点分隔字符串或路径数组
	 * @returns {Array} 解析后的路径段数组
	 */
	function parsePath(path){
		let result = []
		// 处理字符串路径：按点分割
		if (typeof path === 'string') result = path.split('.')
		// 处理数组路径：直接使用
		if (Array.isArray(path)) result = path

		// 遍历路径段，处理带索引的路径（如data[0]）
		for(let i = 0;i<result.length;i++){
			const item = result[i]
			const leftIndex = item.indexOf('[')
			const rightIndex = item.indexOf(']')

			/* 检测并拆分索引格式路径段 */
			if(leftIndex > 0 && rightIndex > 0 && leftIndex < rightIndex){
				const param = item.slice(0,leftIndex)  // 提取属性名（索引前部分）
				const index = item.slice(leftIndex + 1,rightIndex) // 提取索引内容
				result[i] = param   // 替换当前项为属性名
				result.splice(i + 1,0,index) // 在下一项插入索引
			}
		}
		return result
	}

	/**
	 * 根据路径获取对象深层属性值
	 * @param {Object} obj - 要查询的目标对象
	 * @param {string|Array} path - 属性路径（字符串或数组）
	 * @param {*} [defaultValue=null] - 当路径不存在时返回的默认值
	 * @returns {*} 获取到的属性值或默认值
	 */
	function get(obj,path,defaultValue = null){
		let paths = parsePath(path)  // 解析路径
		let current = obj

		// 逐级遍历路径访问属性
		for(const item of paths){
			/* 路径中断时返回默认值 */
			if (!current || typeof current !== 'object') return defaultValue
			current = current[item]
		}
		return current === undefined ? defaultValue : current
	}

	/**
	 * 根据路径设置对象深层属性值，自动创建中间路径
	 * @param {Object} obj - 要操作的目标对象
	 * @param {string|Array} path - 属性路径（字符串或数组）
	 * @param {*} value - 要设置的属性值
	 * @returns {Object} 修改后的原对象
	 */
	function set(obj,path,value){
		let paths = parsePath(path)  // 解析路径
		let current = obj

		/* 遍历到倒数第二级路径，确保中间对象存在 */
		for(let i = 0;i < paths.length - 1;i++){
			const key = paths[i]
			// 当前路径不存在或非对象时创建空对象
			if (!current[key] || typeof current[key] !== 'object') current[key] = {}
			current = current[key]
		}

		// 设置最终属性值
		current[paths[paths.length - 1]] = value
		return obj
	}
</script>

</html>